package com.kurumi.util;


import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import javax.imageio.ImageIO;

import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.util.Matrix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.kurumi.util.thread.PdfRenderThread;

public class PDFUtil {
	private static Logger log = LoggerFactory.getLogger(PDFUtil.class);

	
	/**
	 * PDF文件转图片
	 * 
	 * @param pdfFilePath
	 *            PDF文件路径
	 * @param targetFilePath
	 *            图片文件路径不包含图片名称
	 * @return
	 * @throws IOException
	 */
	public static List<String> pdf2Image(String pdfFilePath, String targetFilePath) throws Exception {
		File file = new File(pdfFilePath);
		List<String> imgFileList = new ArrayList<>();
		if (!file.exists()) {
			return imgFileList;
		}
		PDDocument document = PDDocument.load(file);
		PDFRenderer render = new PDFRenderer(document);
		BufferedImage image = null;
		try {

			int pageCount = document.getNumberOfPages();
			String fileName = null;

			for (int i = 0; i < pageCount; i++) {
				fileName = StringUtil.getFileName() + ".png";
				image = render.renderImage(i, 2.5f);
				ImageIO.write(image, "png", new File(targetFilePath + fileName));
				image.flush();
				imgFileList.add(targetFilePath + fileName);

			}
		} finally {
			if (document != null)
				document.close();
			if (render != null)
				render = null;
			if (image != null)
				image = null;
		}

		return imgFileList;
	}

	/**
	 * PDF转为图片
	 * 
	 * @param pdfPath
	 *            pdf路径
	 * @param imagePath
	 *            文件存放路径
	 * @return 图片名称集合
	 */
	public static List<String> pdf2Img1(String pdfPath, String imagePath) throws Exception{
		List<String> imageList = new LinkedList<String>();
		File file = new File(pdfPath);
		BufferedImage image = null;
		PDDocument doc = null;
		PDFRenderer render = null;
		
		try {
			doc = PDDocument.load(file);
			render = new PDFRenderer(doc);
			int pageCount = doc.getNumberOfPages();
			for (int i = 0; i < pageCount; i++) {
				System.out.println("pdf2Img------------" + i);
				image = render.renderImageWithDPI(i, 197f); 
				String fileName = StringUtil.getFileName() + ".png";
				ImageIO.write(image, "png", new File(imagePath + fileName));
				image.flush();
				imageList.add(fileName);
			}
		}  finally {
			try {
				if (doc != null)
					doc.close();
				if (image != null) {
					image = null;
				}
				
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}

		return imageList;

	}


	/**
	 * 合并pdf文件
	 * 
	 * @param files
	 * @param savepath
	 * @throws IOException 
	 * @throws  
	 */
	public static void mergePdfFiles(String[] files, String savepath) throws Exception {
		Document document = null;
		OutputStream outPutStream = null;
		PdfCopy copy = null;
		PdfReader pdfReader = null;
		
		try {
			pdfReader = new PdfReader(files[0]);
			document = new Document(pdfReader.getPageSize(1));
			document.setPageSize(PageSize.A5);
			outPutStream = new FileOutputStream(savepath);
			copy = new PdfCopy(document, outPutStream);
			document.open();
			
			for (int i = 0; i < files.length; i++) {
					PdfReader reader = new PdfReader(files[i]);
					
					try {
						int n = reader.getNumberOfPages();
						for (int j = 1; j <= n; j++) {
							document.newPage();
							PdfImportedPage page = copy.getImportedPage(reader, j);
							copy.addPage(page);
						}
						
					}  finally {
						if (reader != null) {
							reader.close();
						}
					}
			
			}
		} finally {
			if (null != copy) {
				copy.close();
			}
			
			if (pdfReader != null) {
				pdfReader.close();
			}
			
			if (null != document) {
				document.close();
			}
			if (null != outPutStream) {
				outPutStream.close();
			}
		}
	}


	/**
	 * 图片转PDF
	 * 
	 * @param imgFileNameArr
	 * 
	 * @param pdfFilePath
	 * @return
	 * @throws Exception
	 */
	public static String img2PDF(String[] imgFileNameArr, String pdfFilePath) throws Exception {
		OutputStream out = null;
		Document document = null;
		try {
			out = new FileOutputStream(new File(pdfFilePath));
			document = new Document(null, 0, 0, 0, 0);
			document.setPageSize(PageSize.A5);
			PdfWriter.getInstance(document, out);
			document.open();
			for (String path : imgFileNameArr) {
				Image image = Image.getInstance(path);
				float imageHeight = image.getScaledHeight();
				float imageWidth = image.getScaledWidth();
				int i = 0;
				while (imageHeight > PageSize.A5.getHeight() || imageWidth > PageSize.A5.getWidth()) {
					image.scalePercent(100 - i);
					i++;
					imageHeight = image.getScaledHeight();
					imageWidth = image.getScaledWidth();
				}
				image.setAlignment(Image.ALIGN_CENTER);

				// 插入一个图片
				document.add(image);

			}

		} finally {
			if (null != document) {
				document.close();
			}
			if (null != out) {
				out.close();
			}
		}

		return pdfFilePath;
	}
	
	
	public static List<String> pdf2Img(String pdfPath, final String imagePath) throws Exception{
		List<String> imageList = new LinkedList<String>();
		File file = new File(pdfPath);
		PDDocument doc = null;
		PDFRenderer render = null;
		
		try {
			doc = PDDocument.load(file);
			render = new PDFRenderer(doc);
			int pageCount = doc.getNumberOfPages();
			
			int pageSize = 4;
			int maxThreadNum = 10;
			if (pageCount > 40) {
				pageSize = pageCount/maxThreadNum;
			}
			
			int threadNumber = 0;
			if (pageCount % pageSize != 0) {
				threadNumber = pageCount/pageSize + 1;
			} else {
				threadNumber = pageCount/pageSize;
			}
			
			CountDownLatch latch = new CountDownLatch(threadNumber);
			List<Integer> pageList = new LinkedList<Integer>();
			List<String> fileNameList = new LinkedList<String>();
			int threadCount = 0;
			
			for (int i = 0; i < pageCount; i++) {
				//String fileName =  StringUtil.getId() + ".jpg";
				String fileName =  i + ".jpg";
				imageList.add(fileName);
				fileNameList.add(fileName);
				pageList.add(i);
				if ((i+1) % pageSize == 0) {
					PdfRenderThread pdfRenderThread = new PdfRenderThread(render, pageList,fileNameList, imagePath, pdfPath ,latch);
					threadCount++;
					new Thread(pdfRenderThread).start();
					pageList = new LinkedList<Integer>();
					fileNameList = new LinkedList<String>();
				}
			}
			
			if (pageList.size() > 0) {
				PdfRenderThread pdfRenderThread = new PdfRenderThread(render, pageList, fileNameList, imagePath, pdfPath, latch);
				new Thread(pdfRenderThread).start();
				threadCount++;
			}
			System.out.println("threadCount = " + threadCount );
			latch.await();
		}  finally {
			try {
				if (doc != null)
					doc.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}

		return imageList;
	}
	
	
	/**
	 * 获取PDF有多少页
	 * @param pdfPath
	 * 		PDF文件路径
	 * @return
	 * @throws Exception
	 */
	public static int getPDFPages(String pdfPath) throws Exception {
		File file = new File(pdfPath);
		int pageCount = 0;
		if (!file.exists()) {
			return 0;
		}
		PDDocument document = PDDocument.load(file);
		PDFRenderer render = new PDFRenderer(document);
		BufferedImage image = null;
		try {

			 pageCount = document.getNumberOfPages();
			
		} finally {
			if (document != null)
				document.close();
			if (render != null)
				render = null;
			if (image != null)
				image = null;
		}

		return pageCount;
	}
	
	public static byte[] watermarkPDF(byte[] fileStored, String text) throws Exception{
		byte[] byteArray = null;
		ByteArrayOutputStream bos = null;
		PDPageContentStream cs = null;
		
		try {
			 bos =new ByteArrayOutputStream();
			 PDDocument doc =PDDocument.load(fileStored);
			 doc.setAllSecurityToBeRemoved(true);
			 
			 for (PDPage page : doc.getPages()) {
				  cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
				  PDFont font = PDTrueTypeFont.loadTTF(doc, new File("C:\\Users\\h2oco2\\Desktop\\simsun.ttf")); 
				  
				 float fontSize =50.0f;
				 PDExtendedGraphicsState r0 =new PDExtendedGraphicsState();
				 //font.encode(text);
				 
				 // 透明度
				 r0.setNonStrokingAlphaConstant(0.2f);
				 r0.setAlphaSourceFlag(true);
				 cs.setGraphicsStateParameters(r0);
				
				 cs.beginText();
				 cs.setFont(font,fontSize);
				 
				 // 获取旋转实例
				 cs.setTextMatrix(Matrix.getRotateInstance(100, 200f, 800f));
				 cs.drawString(new String("毓璜顶医院".getBytes("utf-8")));
				 //cs.showText("aaaaa");
				 cs.endText();
				 cs.close();
				 
				/* cs.beginText();
				 cs.setFont(font,fontSize);
				 // 获取旋转实例
				 cs.setTextMatrix(Matrix.getRotateInstance(100,200f, 300f));
				 cs.drawString(new String("毓璜顶医院".getBytes("utf-8")));
				// cs.showText(new String("毓璜顶医院".getBytes("utf-8")));
				 cs.endText();
				 cs.close();*/
			 }
			 
			 doc.save(bos);
			 byteArray = bos.toByteArray();
		} finally {
			if (null != bos) {
				bos.close();
			}
			
			if (null != cs) {
				cs.close();
			}
			
			fileStored = null;
		}
		
		return byteArray;
	}
	
//	public static void main(String[] args) throws Exception {
//		String filePath = "C:\\Users\\h2oco2\\Desktop\\xxxx.PDF";
//		byte[] b = watermarkPDF(FileUtil.toByteArray(filePath), "毓璜顶医院");
//		
//		FileOutputStream out = new FileOutputStream(new File("C:\\Users\\h2oco2\\Desktop\\xxxx1.PDF"));
//		out.write(b);
//		out.flush();
//		out.close();
//		b = null;
//	}
	
	
	public static void main(String[] args) throws Exception {
		/*
		 * try { pdf2Img("D://pdf/3.pdf","D://3/"); } catch (Exception e) { // TODO
		 * Auto-generated catch block e.printStackTrace(); }
		 */
	
		List<String> list = new LinkedList<>();
		for(int i=75;i<=98;i++) {
			list.add("D://4/"+i+".jpg");
		}
		String[] strings = new String[list.size()];

		String[] arr = list.toArray(strings);
		for (String string : arr) {
			System.out.println(string);
		}
		
		img2PDF(arr, "D://1/4(76)-4(99).pdf");
		
	}
	
	
	
	
	/*public static void main(String[] args) throws Exception {
		List<String> pdfList = new LinkedList<String>();
		String fielPath = "D://publics/print/"+DateUtil.dateFormat("yyyy-MM-dd", new Date())+"/";
		String fileName = MD5.md5("111111"+"33")+".PDF";
		File folder = new File(fielPath);
		if(!folder.exists()){
			folder.mkdirs();
		}
		
		

		for (int i = 0; i < 20; i++) {
			pdfList.add("D://PDF/"+i+".PDF");
		}
		
		String[] array = new String[pdfList.size()];
		array = pdfList.toArray(array);
		long before = new Date().getTime();
		
		mergePdfFiles(array,fielPath+fileName);
		long after = new Date().getTime();
		System.out.println("转化数据时间="+ (after-before)/1000/60);
		
		
	}*/


}
